﻿/* lrc歌词同步的类
 * 用法很简单，通过一个string(歌词内容)构造一个这个类，然后通过类中的FindLrc(int time)方法获得指定时间的歌词
 * By Eleven @ 2010/7/30
 * */


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using ZMenFM.BASS;

namespace ZMenFM.Ramification.nBassTest
{
    //从示例中把歌词同步的部分分出来，以便给重新写歌词部分的UI。
    //通过一段歌词 实现 输入一个时间直接得到一段歌词
    class synchroLrc
    {
        private List<Lrc> lrcList = new List<Lrc>();
        public Int32 channel = 0;
        public string lrc;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="channel">频道</param>
        public synchroLrc(string lrc)
        {
            this.lrc = lrc;
            regLrc(lrc);
        }

        /// <summary>
        /// 歌词的结构体
        /// </summary>
        private struct Lrc
        {
            public int sTime;    //时间
            public string sText;    //歌词内容
            #region 歌词构造函数
            /// <summary>
            /// 一句歌词（Lrc）构造函数
            /// </summary>
            /// <param name="_sTime">播放时间</param>
            /// <param name="_sText">歌词内容</param>
            public Lrc(int _sTime, string _sText)
            {

                sTime = _sTime;
                sText = _sText;
            }
            #endregion
        }
        /// <summary>
        /// 分析歌词，将每句歌词分开，写入lrcList中
        /// </summary>
        /// <param name="lrcContent">歌词内容</param>
        private void regLrc(string lrcContent)
        {
            lrcList.Clear();
            //string sPattner="(?<t>\\[\\d[^[]+])(?<w>.*\r\n)";
            string sPattner = "(?<t>\\[\\d.*\\]+)(?<w>[^\\[])";
            sPattner = @"(?<t>\[\d\d:\d\d\.\d\d\])(?<w>([^\[])+)";
            Regex reg = new Regex(sPattner);
            foreach (Match mc in reg.Matches(lrcContent))
            {
                lrcList.Add(new Lrc(TimeToInt(mc.Groups["t"].ToString()), mc.Groups["w"].ToString()));
            }
        }
        //将字符串时间转换成数值型的
        private static int TimeToInt(string timeString)
        {
            int time = 0;
            int minute = Int32.Parse(timeString.Substring(1, 2));
            int second = Int32.Parse(timeString.Substring(4, 2));
            time = minute * 60 + second;
            return time;
        }

        private int position = 0;       //当前歌词的播放位置
        /// <summary>
        /// 寻找指定时间的
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public string FindLrc(int time)
        {
            //如果当前位置比当前lrc的时间大，比后一个lrc的时间小，则返回当前歌词内容
            if (position < lrcList.Count && time >= lrcList[position].sTime && time < lrcList[position + 1].sTime)
            {
                return lrcList[position].sText;
            }
            //如果时间比当前下一条歌词的时间大或者相等，比下一条的下一条小，则返回下一条歌词内容，并把歌词位置向后一个
            if (position + 2 < lrcList.Count && time >= lrcList[position + 1].sTime && time < lrcList[position + 2].sTime)
            {
                position++;
                return lrcList[position].sText;
            }
            //歌词到达最后一条
            if (time >= lrcList[lrcList.Count - 1].sTime)
            {
                return lrcList[lrcList.Count - 1].sText;
            }
            //歌曲播放进度被调整，重新寻找歌词位置
            for (int i = 0; i < lrcList.Count - 1; i++)
            {
                if (time >= lrcList[i].sTime && time < lrcList[i + 1].sTime)
                {
                    position = i;
                    return lrcList[i].sText;
                }
            }
            return "";//找不到返回空字符串
        }
    }
}
